import React, { useState } from 'react';
import { SimpleForm as Form, Button, Input, Select, Radio, DatePicker, InputNumber, message, Switch } from '@whalecloud/fdx';
import DesignUserSelect from '@components/BatchEdit/components/DesignUserSelect';
import { ReactComponent as AddSvg } from '@/assets/icons/add-circle.svg';
import { ReactComponent as MinusSvg } from '@/assets/icons/minus-circle.svg';
import './batchEdit.module.less';

const { Option } = Select;
const dataList = [
  {
    name: 'projectId', type: 'Long', label: 'projectId',
  },
  {
    name: 'projectName', type: 'TextArea', label: 'projectName',
  },
  {
    name: 'createDate', type: 'Date', label: 'createDate',
  }
];
const BatchEdit = (props: any) => {
  const { dataSource = dataList, onChange } = props;

  // 获取数据源
  const [form] = Form.useForm();
  const batchDataList = dataSource || [];

  /**
   * 加载默认值根据类型
   * @param type
   * @returns
   */
  const renderValueByType = (type: string) => {
    if (type === 'Boolean') {
      return false;
    } else if (type === 'Long') {
      return 0;
    } else return null;
  };

  // initvalue, 默认显示多项
  const initialValues = {
    "editList": dataSource.map((curValue: any) => ({
      first: curValue.name,
      last: renderValueByType(curValue.type),
      valueType: '0',
    })),
  };

  // radio
  const radioList = {
    0: '修改为新值',
    1: '清空内容',
  };
  const radioKeyList = Object.keys(radioList);

  // radio选择数据，关联是否显示隐藏
  const [radioProps, setRadioProps] = useState({});
  // 下拉框数据，（实时，剩下的）
  const [restDataList, setRestDataList] = useState(batchDataList);

  /**
   * radio操作返回函数
   * @param e event事件
   * @param key Form.List项的key
   */
  const handleRadioChange = (e: any, key: any) => {
    setRadioProps({ ...radioProps, [key]: e.target.value });
  };

  /**
   * 字段选择下拉框，打开下拉部分时返回函数，也是Focus返回函数
   * @param curName // Form.List当前部分的key为curName字段，和key有区别
   */
  const handleSelectFocus = (curName: any) => {
    // 下拉部分：所有项去掉其他项
    const getFormValue = form.getFieldsValue(true).editList; //获取表单值
    const keyValue = getFormValue[curName].first;
    const valueList = getFormValue.filter((curValue: any) => curValue.first && curValue.first !== keyValue).map((curValue: any) => curValue.first);
    const restList = batchDataList.filter((curValue: any) => !valueList.includes(curValue.name));
    setRestDataList(restList);
  };

  /**
   * select选项变化时，组件根据选项变化
   * @param curName 
   */
  const handleSelectChange = (curName) => {
    handleSelectFocus(curName);
  }

  /**
   * form的change返回函数
   */
  const handleFormChange = () => {
    const getFormValue = form.getFieldsValue(true).editList;
    const dataObj = {};
    if (getFormValue.length > 0) {
      getFormValue.map((curValue: any) => {
        if (curValue) {
          const getNameArr = dataSource.filter((curItem: any) => curItem.name === curValue.first);
          dataObj[getNameArr[0].name] = curValue.valueType === '0' ? curValue.last : null;
        } else if (restDataList.length > 0) {
          // 新增时监控不到，这里判断增加
          dataObj[restDataList[0].name] = renderValueByType(restDataList[0].type);
        }
      });
    }
    onChange(dataObj);
  };

  /**
   * 表单新增一项的返回函数
   * @param add // 新增一项的方法
   * @returns 
   */
  const handleAdd = (add: any) => {
    const getFormValue = form.getFieldsValue(true).editList;
    let getAddArr;

    // 如果已经达到最大项，提示不能新增
    if ((getFormValue && getFormValue.length === batchDataList.length) || dataSource.length === 0) {
      message.success('已经到达最大项，请删除后再新增!');
      return;
    }
    // 新增时下拉框list会变化
    if (getFormValue && getFormValue.length > 0) {
      const getRest = getFormValue.map((curValue: any) => curValue?.first);
      const getRestList = batchDataList.filter((curValue: any) => !getRest.includes(curValue.name));
      setRestDataList(getRestList);
      getAddArr = getRestList.slice(0, 1);
    } else {
      setRestDataList(batchDataList);
      getAddArr = batchDataList.slice(0, 1);
    }
    getAddArr = getAddArr.map((curValue: any) => ({
      first: curValue.name,
      last: renderValueByType(curValue.type),
      valueType: '0',
    }));

    add();
    form.setFieldsValue({
      editList: [...getFormValue, ...getAddArr],
    });
  }

  /**
   * 删除Form.List项
   * @param curName // 当前项的Key
   * @param remove // 删除方法
   */
  const handleRemove = (curName: any, remove: any) => {
    remove(curName);

    // 删除后，下拉框列表的变化
    const getFormValue = form.getFieldsValue(true).editList;
    const getFormKey = getFormValue.map((curValue: any) => curValue.name);
    const getRest = batchDataList.filter((curValue: any) => !getFormKey.includes(curValue.name));
    setRestDataList(getRest);
  };

  /**
   * 渲染字段field下拉选择部分
   * @param restDataList // 下拉框list变量
   * @returns 
   */
  const renderFieldKeyFirst = (restDataList = []) => {
    return restDataList.map((curValue: any) => (<Option value={curValue.name}>{curValue.label}</Option>))
  };

  /**
   * 渲染组件字段名
   * @param curName // Form.List当前部分的key为curName字段，和key有区别
   * @returns
   */
  const renderCompLabel = (curName: any) => {
    const getFormValue = form.getFieldsValue(true).editList;
    const keyValue = getFormValue[curName]?.first || '';
    return `${keyValue}:`;
  };

  /**
   * 按照类型渲染组件，有输入框等组件
   * @param curName  // Form.List当前部分的key为curName字段，和key有区别
   * @returns 
   */
  const renderCompByType = (curName: any) => {
    // 获取表单当前项，定位type类型
    const getFormValue = form.getFieldsValue(true).editList;
    const keyValue = getFormValue[curName]?.first || '';
    const getType = dataSource.filter((curValue: any) => curValue.name === keyValue)[0]?.type || restDataList[0]?.type;

    // 根据类型渲染组件
    if (getType === 'Long') {
      return <InputNumber min={0} />
    } else if (getType === 'Date') {
      return <DatePicker />
    } else if (getType === 'UserSingle') {
      return <DesignUserSelect />
    } else if (getType === 'Boolean') {
      return <Switch />
    } else {
      return <Input placeholder="" />
    }
  };

  return (
    <Form
      form={form}
      initialValues={initialValues}
      onValuesChange={handleFormChange}
    >
      <Form.List name="editList" colon={true}>
        {(fields: any, { add, remove }: any) => (
          <>
            {fields.map(({ key, name, fieldKey, ...restField }: any) => {
              return (
                <>
                  <div className="relative">
                    <MinusSvg className="batch-edit-icon batch-edit-icon-minus" onClick={() => handleRemove(name, remove)} />
                  </div>
                  <Form.Item
                    {...restField}
                    name={[name, 'first']}
                    fieldKey={[fieldKey, 'first']}
                    label={<div style={{ width: 100 }}>字段</div>}
                  >
                    {
                      dataSource.length > 0
                      ? (
                        <Select
                          className="batch-edit-select"
                          bordered={false}
                          onChange={() => handleSelectChange(name)}
                          onFocus={() => handleSelectFocus(name)}
                        >
                          {renderFieldKeyFirst(restDataList)}
                        </Select>
                      )
                      : 'null'
                    }
                  </Form.Item>
                  <Form.Item
                    {...restField}
                    name={[name, 'valueType']}
                    fieldKey={[fieldKey, 'valueType']}
                    label={<div style={{ width: 100 }}>字段内容</div>}
                  >
                    <Radio.Group name={`batch_edit_${key}`} onChange={e => handleRadioChange(e, key)}>
                      {Object.keys(radioList).map(curValue => <Radio value={curValue}>{radioList[curValue]}</Radio>)}
                    </Radio.Group>
                  </Form.Item>
                  {
                    radioProps[key] !== '1'
                      ? (
                        <Form.Item
                          {...restField}
                          name={[name, 'last']}
                          label={<div style={{ paddingLeft: '123px' }}>{dataSource.length > 0 ? renderCompLabel(name) : ''}</div>}
                          fieldKey={[fieldKey, 'last']}
                        >
                          {renderCompByType(name)}
                        </Form.Item>
                      )
                      : (
                        <div />
                      )
                  }
                </>
              )
            }
            )}
            <Form.Item>
              <Button type="dashed" className="flex items-center justify-center" onClick={() => handleAdd(add)} block>
                <AddSvg className="batch-edit-icon batch-edit-icon-add" /> 增加一项
              </Button>
            </Form.Item>
          </>
        )}
      </Form.List>
    </Form>
  );
};

export default React.memo(BatchEdit);
